/*
*	Project: Aethon
*
*	File: Quaternion.cpp
*
*	Author: Jonathan Hersack
*
*	Date: 3/27/2009
*
*   Purpose: defines quaternion for use with control and eye rotations.
*	Based on NEHE Productions tutorial.
*	http://nehe.gamedev.net/data/lessons/lesson.asp?lesson=Quaternion_Camera_Class
*/

#include "../include/Quaternion.h"

void Quaternion::CreateFromAxisAngle(float x, float y, float z, float degrees)
{
  //float radianAngle = degrees/(2*PI);
  float radianAngle = degrees/(2*PI);
  float sinAngle = sin(radianAngle/2.0);
  
  W = cos(radianAngle/2.0);
  //W = cos(radianAngle);
  X = x*sinAngle;
  Y = y*sinAngle;
  Z = z*sinAngle;
  
}//end createfromaxisangle


void Quaternion::CreateMatrix(float *Matrix)
{//copied from tutorial cited in comment block
  // Make sure the matrix has allocated memory to store the rotation data
	if(!Matrix) return;

	// First row
	Matrix[ 0] = 1.0f - 2.0f * ( Y * Y + Z * Z ); 
	Matrix[ 1] = 2.0f * (X * Y + Z * W);
	Matrix[ 2] = 2.0f * (X * Z - Y * W);
	Matrix[ 3] = 0.0f;  

	// Second row
	Matrix[ 4] = 2.0f * ( X * Y - Z * W );  
	Matrix[ 5] = 1.0f - 2.0f * ( X * X + Z * Z ); 
	Matrix[ 6] = 2.0f * (Z * Y + X * W );  
	Matrix[ 7] = 0.0f;  

	// Third row
	Matrix[ 8] = 2.0f * ( X * Z + Y * W );
	Matrix[ 9] = 2.0f * ( Y * Z - X * W );
	Matrix[10] = 1.0f - 2.0f * ( X * X + Y * Y );  
	Matrix[11] = 0.0f;  

	// Fourth row
	Matrix[12] = 0;  
	Matrix[13] = 0;  
	Matrix[14] = 0;  
	Matrix[15] = 1.0f;

	// Now Matrix[] is a 4x4 homogeneous matrix that can be applied to an OpenGL Matrix

}//end creatematrix


Quaternion Quaternion::operator* (Quaternion q)
{
//copied from tutorial cited in comment block
Quaternion r;

	r.W = W*q.W - X*q.X - Y*q.Y - Z*q.Z;
	r.X = W*q.X + X*q.W + Y*q.Z - Z*q.Y;
	r.Y = W*q.Y + Y*q.W + Z*q.X - X*q.Z;
	r.Z = W*q.Z + Z*q.W + X*q.Y - Y*q.X;
	
	return(r);
}
